package com.hope.service.impl;

import com.hope.domain.dto.LoginFormDTO;
import com.hope.domain.dto.UserDTO;
import com.hope.domain.pojo.Result;
import com.hope.domain.pojo.User;
import com.hope.domain.vo.LoginVO;
import com.hope.mapper.UserMapper;
import com.hope.service.UserService;
import com.hope.util.JwtUtil;
import com.hope.util.RedisConstant;
import com.hope.util.VerificationCode;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

import static com.hope.util.RedisConstant.EXPIRE_TIME;
import static com.hope.util.RedisConstant.SENT_TIME;

@Service
public class UserServiceImpl implements UserService {
    //导入application.yml里面的发件人邮箱
    @Value("${spring.mail.username}")
    private String fromEmail;

    @Autowired
    JavaMailSender sender;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Result getUserAllInfo(Long id) {
        if(id == null||id==0) {
            return Result.fail("id为空");
        }
        User user = userMapper.getUserAllInfo(id);

        if(user==null){
            return Result.fail("未查到id为"+id+"用户");
        }
        return Result.ok(user);
    }

    @Override
    public User login(LoginFormDTO user) {
        return userMapper.login(user);
    }

    @Override
    public int register(LoginFormDTO user) {
        return userMapper.register(user);
    }

    @Override
    public User findUserByName(String name) {
        return userMapper.findUserByName(name);
    }

    @Override
    public UserDTO findUserByUsername(String name) {
        return userMapper.findUserByUsername(name);
    }

    @Override
    public int forget(LoginFormDTO user) {
        return userMapper.forget(user);
    }

    /**
     * 发送验证码 （带防刷）
     * @param toEmail
     * @return
     */
    @Override
    public int sendCode(String username,String toEmail) {
        //增加唯一set  email:code:3402351070@qq.com
        String sentKey= RedisConstant.EMAIL_SENT + username + toEmail;
        if(Boolean.TRUE.equals(stringRedisTemplate.hasKey(sentKey))){
            return 2;
        }
        try {
            System.out.println(fromEmail);
            String code= VerificationCode.generateVerificationCode();
            //存入验证码到 redis 里面
            String codeKey= RedisConstant.EMAIL_CODE +username+ toEmail;
            stringRedisTemplate.opsForValue().set(codeKey,code,EXPIRE_TIME,TimeUnit.SECONDS);

            //存入 防刷标记 到 redis 里面
            stringRedisTemplate.opsForValue().set(sentKey,"1",SENT_TIME,TimeUnit.SECONDS);
            //发送邮件验证码
            System.out.println(code);
            SimpleMailMessage msg = new SimpleMailMessage();
            msg.setFrom(fromEmail);
            msg.setTo(toEmail);
            msg.setSubject("Hope外卖-使命必达");
            msg.setText("您的验证码是：" + code + "，5分钟内有效，请勿泄露");
            sender.send(msg);
            return 1;
        } catch (MailException e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 验证码（校对）
     * @param email
     * @param code
     * @return
     */
    public int verifyCode(String username,String email, String code) {
        try {
            String codeKey = RedisConstant.EMAIL_CODE + username + email;
            String string = stringRedisTemplate.opsForValue().get(codeKey);
            if (string == null) {
                return 0;
            }
//        验证密码成功
            if (string.equals(code)) {
                stringRedisTemplate.delete(codeKey);
                return 1;
            }
            return 0;
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }

    @Override
    public int edit(User user) {
        return userMapper.edit(user);
    }

    @Override
    public Result refreshToken(String accessToken, HttpServletResponse response) {
        Claims claims = null;
        try {
            claims = JwtUtil.parseToken(accessToken);
            System.out.println(claims);
        } catch (Exception e) {
            System.out.println(claims);
            System.out.println("长token过期了,token expired");
            return Result.fail(401,"长token过期了,token expired");
        }
        System.out.println(claims.getId());
        System.out.println(222);
        Long id = Long.valueOf(claims.getSubject());
        System.out.println(id);
        User user = userMapper.getUserAllInfo(id);
        if(user==null){
            return Result.fail(401,"用户不存在,你竟然测试我");
        }
        //更新双 token 回去
        String AccessToken = JwtUtil.createToken(String.valueOf(id));
        String RefreshToken = JwtUtil.createRefreshToken(String.valueOf(id));
        response.setHeader("AccessToken", AccessToken);
        response.setHeader("RefreshToken",RefreshToken);
        System.out.println(AccessToken);
        System.out.println(RefreshToken);

        LoginVO loginVO = new LoginVO(
                AccessToken,
                RefreshToken,
                user.getId().toString(),  // id
                user.getUsername(),       // username
                user.getNickname(),       // nickname
                user.getAvatar(),         // avatar
                user.getRole(),           // role
                user.getEmail(),          // email
                user.getStatus()          // status
        );
        return Result.ok(loginVO);
    }

    @Override
    public Result getUserInfo(Long id) {
        if(id == null||id==0) {
            return Result.fail("id为空");
        }
        UserDTO user = userMapper.getUserInfo(id);

        if(user==null){
            return Result.fail("未查到id为"+id+"用户");
        }
        return Result.ok(user);
    }

    @Override
    public Result updateAvatar(String avatar, Long id) {
        int i = userMapper.updateAvatar(avatar,id);
        if(i==0){
            return Result.fail("未更新成功");
        }
        return Result.ok("更新成功");
    }
}
